home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Night Owl 8
/
Night Owl CD-ROM (NOPV8) (Night Owl Publisher) (1993).ISO
/
047a
/
lex_yacc.arj
/
CREF.L
next >
Wrap
Text File
|
1989-05-28
|
6KB
|
191 lines
%{
(* CREF.L: simple Turbo Pascal cross reference utility
USAGE: cref <input-file >output-file
DESCRIPTION: Produces a cross reference listing from the input-file
(.pas suffix must be specified), written to the output-file (if source
and target file redirection is ommitted, input comes from stdin, and
output goes to stdout)
EXAMPLE: cref <myprog.pas >prn *)
program cref;
uses LexLib;
type Ident = string[80];
function upper(id : Ident) : Ident; forward;
(* converts id to uppercase *)
function is_keyword(id : Ident) : boolean; forward;
(* checks whether id is a Turbo Pascal keyword *)
procedure enter(id : Ident; lineno : integer); forward;
(* enter id and lineno into binary tree, sorted in lexical order of
identifiers *)
procedure print; forward;
(* prints out the binary tree in inorder *)
%}
%start code str comment1 comment2
letter [A-Za-z_]
digit [0-9]
%%
{ print line numbers: }
\n begin
echo;
write(yyout, yylineno:4, ': ')
end;
{ echo keywords and enter identifier occurrences into binary tree
(converted to uppercase): }
<code>{letter}({letter}|{digit})*
begin
echo;
if not is_keyword(yytext) then
enter(upper(yytext), yylineno)
end;
{ rules to handle strings, comments, and hexadecimals: }
<code>' begin echo; begin_(str) end;
<str>'' echo;
<str>' begin echo; begin_(code) end;
<code>"(*" begin echo; begin_(comment1) end;
<code>"{" begin echo; begin_(comment2) end;
<comment1>"*)" begin echo; begin_(code) end;
<comment2>"}" begin echo; begin_(code) end;
<code>"$"({digit}|[A-Fa-f])+ echo;
%%
function upper(id : Ident) : Ident;
var i : integer;
begin
for i := 1 to length(id) do
id[i] := upCase(id[i]);
upper := id
end(*upper*);
function is_keyword(id : Ident) : boolean;
(* table of Turbo Pascal keywords: *)
const
no_of_keywords = 48;
keyword : array [1..no_of_keywords] of Ident = (
'ABSOLUTE', 'AND', 'ARRAY', 'BEGIN', 'CASE',
'CONST', 'DIV', 'DO', 'DOWNTO', 'ELSE',
'END', 'EXTERNAL', 'FILE', 'FOR', 'FORWARD',
'FUNCTION', 'GOTO', 'IF', 'IMPLEMENTATION', 'IN',
'INLINE', 'INTERFACE', 'INTERRUPT', 'LABEL', 'MOD',
'NIL', 'NOT', 'OF', 'OR', 'PACKED',
'PROCEDURE', 'PROGRAM', 'RECORD', 'REPEAT', 'SET',
'SHL', 'SHR', 'STRING', 'THEN', 'TO',
'TYPE', 'UNIT', 'UNTIL', 'USES', 'VAR',
'WHILE', 'WITH', 'XOR');
var m, n, k : integer;
begin
id := upper(id);
m := 1; n := no_of_keywords;
is_keyword := true;
while m<=n do
begin
k := m+(n-m) div 2;
if id=keyword[k] then
exit
else if id>keyword[k] then
m := k+1
else
n := k-1
end;
is_keyword := false
end(*is_keyword*);
type
(* binary tree for identifiers, sorted in lexical order of idents,
and linked list of integers (line numbers) *)
BinTree = ^TreeNode;
IntList = ^ListNode;
TreeNode = record
id : Ident;
linenos : IntList;
left, right : BinTree;
end;
ListNode = record
lineno : integer;
next : IntList
end;
var
tree : BinTree;
(* binary tree to store identifier occurrences *)
procedure enter(id : Ident; lineno : integer);
procedure enter_id(var tree : BinTree; id : Ident; lineno : integer);
(* enter id, lineno into tree *)
procedure enter_lineno(var linenos : IntList; lineno : integer);
(* append lineno to linenos *)
begin
if linenos=nil then
begin
new(linenos);
linenos^.lineno := lineno;
linenos^.next := nil
end
else
enter_lineno(linenos^.next, lineno)
end(*enter_lineno*);
begin
if tree=nil then
(* add new leave *)
begin
new(tree);
tree^.id := id;
tree^.linenos := nil;
tree^.left := nil; tree^.right := nil;
enter_lineno(tree^.linenos, lineno)
end
else if tree^.id=id then
(* add lineno to the linenos list of this node *)
enter_lineno(tree^.linenos, lineno)
else if tree^.id>id then
(* enter into left subtree *)
enter_id(tree^.left, id, lineno)
else
(* enter into right subtree *)
enter_id(tree^.right, id, lineno)
end(*enter_id*);
begin
enter_id(tree, id, lineno)
end(*enter*);
procedure print;
procedure print_ids(tree : BinTree);
(* print out tree (inorder) *)
procedure print_linenos(linenos : IntList);
(* print linenos list *)
begin
if linenos<>nil then with linenos^ do
begin
write(yyout, lineno, ' ');
print_linenos(next)
end
end(*print_linenos*);
begin
if tree<>nil then with tree^ do
begin
print_ids(left);
write(yyout, ' ', id, ' ');
print_linenos(linenos);
writeln(yyout);
print_ids(right)
end
end(*print_ids*);
begin
writeln(yyout);
writeln(yyout);
print_ids(tree);
end(*print*);
begin
(* initialize binary tree, print line counter: *)
tree := nil;
write(yyout, yylineno:4, ': ');
(* process file with yylex and print out cref list contained in binary
tree *)
begin_(code);
if yylex=0 then ;
print
end.